﻿using System;
using System.Linq;
using System.Text;
using MyUtils;

namespace FitAutomation.FitProcess
{
	/// <summary>
	/// Accessor for object in another process
	/// </summary>
	public class ObjectAccessor : HideObjectMembers
	{
		readonly FitProcessAccessor _fitProcessAccessor;
		readonly string _name;

		internal ObjectAccessor(FitProcessAccessor fitProcessAccessor, string name)
		{
			_fitProcessAccessor = fitProcessAccessor;
			_name = name;
		}

		/// <summary>
		/// See MyUtils.Utils.Reflect
		/// </summary>
		/// <param name="member"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		public T Reflect<T>(string member, params object[] args)
		{
			return (T) Reflect(member, args);
		}

		/// <summary>
		/// See MyUtils.Utils.Reflect
		/// </summary>
		/// <param name="member"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		public object Reflect(string member, params object[] args)
		{
			var buf = args.Any() ? Serializer.SerializePackage(args) : null;
			var msg = "ref;" + _name + ";" + member;
			if (buf != null)
			{
				msg += ";" + Encoding.UTF8.GetString(buf);
			}
			var resp = _fitProcessAccessor.Send(msg);
			var code = (MessageCode)resp;
			if (code == MessageCode.OK)
			{
				return null;
			}
			if (code == MessageCode.ErrorNotMessageCode)
			{
				var objs = Serializer.DeserializePackage(resp);
				var val = objs.FirstOrDefault();
				var ex = val as ExceptionPackage;
				if (ex != null)
				{
					throw new RemoteException(ex.Exception);
				}
				return val;
			}
			throw new Exception(code.ToString());
		}
	}
}